// (C) 2011 L0H
// convert GIF to PAM(RGBA)
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include "gif_lib.h"
using namespace std;

void gif2pam(const string& out, GifFileType* gf) {
	for (int i = 0; i < gf->ImageCount; ++i) {
		SavedImage img = gf->SavedImages[i];
		GifImageDesc imgd = img.ImageDesc;
		ColorMapObject* cmo = imgd.ColorMap;
		if (!cmo)
			cmo = gf->SColorMap;
		// check transparent index
		int tp = -1;
		for (int j = 0; j < img.ExtensionBlockCount; ++j) {
			ExtensionBlock ext = img.ExtensionBlocks[j];
			switch (ext.Function) {
			case 0xF9: // Graphic Control Extension
				cout << "Graphic Control Extension:" << endl;
				if (ext.Bytes[0] & 0x1)
					tp = static_cast<unsigned char>(ext.Bytes[3]);
				cout << "    Transparent Color Index: " << tp << endl;
				break;
			case 0xFE: // Comment Extension
				cout << "Comment Extension: ignore" << endl;
				break;
			case 0x01: // Plain Text Extension
				cout << "Plain Text Extension: ignore" << endl;
				break;
			case 0xFF: // Application Extension
				cout << "Application Extension: ignore" << endl;
				break;
			}
		}
		int size = imgd.Width * imgd.Height;
		vector<char> buf(size*4);
		for (int j = 0; j < size; ++j) {
			int ci = img.RasterBits[j]; // color index
			GifColorType c = cmo->Colors[ci];
			int jj = j * 4;
			buf[jj+0] = c.Red;
			buf[jj+1] = c.Green;
			buf[jj+2] = c.Blue;
			if (ci == tp)
				buf[jj+3] = 0;
			else
				buf[jj+3] = 255;
		}
		stringstream ss;
		ss << out << "[" << i << "].pam";
		ofstream ofs(ss.str().c_str(), ios::binary);
		ofs << "P7" << endl
			<< "WIDTH " << imgd.Width << endl
			<< "HEIGHT " << imgd.Height << endl
			<< "DEPTH " << 4 << endl
			<< "MAXVAL " << 255 << endl
			<< "TUPLTYPE " << "RGB_ALPHA" << endl
			<< "ENDHDR" << endl;
		ofs.write(&buf[0], buf.size());
	}
}

int main(int argc, char** argv) {
	if (argc != 2) {
		cerr << "Usage: ./gif2ppm file.gif" << endl;
		exit(1);
	}
	GifFileType* gf = DGifOpenFileName(argv[1]);
	if (!gf) {
		PrintGifError();
		exit(1);
	}
	if (DGifSlurp(gf) == GIF_ERROR) {
		PrintGifError();
		exit(1);
	}
	// make file name
	string filename(argv[1]);
	gif2pam(filename.substr(0, filename.length()-4), gf);
	DGifCloseFile(gf);
	return 0;
}


